﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AudiPyme.DAL
{
    public static class CriteriosRiesgoFactory
    {
        //Método que inserta un Criterio de Riesgo
        public static void InsertarCriteriosRiesgo(CriteriosRiesgo NuevoCriterio)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            agenteBD.AddToCriteriosRiesgoEstablecer(NuevoCriterio);
            agenteBD.SaveChanges();
        }

        //Método que inserta un Criterio de Riesgo según los valores seleccionados
        public static void InsertarCriteriosRiesgo(String Codigo, String CR, String Descrip)
        {
            CriteriosRiesgo Criterio = new CriteriosRiesgo();
            Criterio.Codigo = Codigo;
            Criterio.CriterioRiesgo = CR;
            Criterio.Descripcion = Descrip;
            Criterio.Actual = true;
            CriteriosRiesgoFactory.InsertarCriteriosRiesgo(Criterio);
        }

        //Método que devuelve el nombre de un criterio de riesgo
        public static String NombreCriterioRiesgo(int IdCriterioRiesgo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> NombreCriterio = from NCriterio in agenteBD.CriteriosRiesgoEstablecer
                                                where NCriterio.IdCriterioRiesgo == IdCriterioRiesgo
                                                select NCriterio.CriterioRiesgo;
            if (NombreCriterio.Count() == 0)
            {
                return "";
            }
            else
            {
                return NombreCriterio.First();
            }
        }

        //Elimina un criterio de riesgo según su nombre
        public static void EliminarCriteriosRiesgo(String CriterioRiesgo)
        {
            //Busco el Id del Criterio de Riesgo seleccionado para eliminar
            ModeloContainer agenteBD = new ModeloContainer();
            CriteriosRiesgo CREliminar = (from Criterio in agenteBD.CriteriosRiesgoEstablecer
                                          where Criterio.CriterioRiesgo == CriterioRiesgo
                                          select Criterio).Single();
            agenteBD.SaveChanges();
        }

        //Indica si el código de un criterio de riesgo está en la base de conocimiento 
        public static bool EstaCodigo(String Codigo)
        {
            bool estaCodigo = false;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> Codigos = from CodigosCriterio in agenteBD.CriteriosRiesgoEstablecer
                                         select CodigosCriterio.Codigo;
            foreach (String c in Codigos)
            {
                if (c.Equals(Codigo))
                {
                    estaCodigo = true;
                }
            }
            return estaCodigo;
        }

        //Indica si el código de un criterio de riesgo y su identificador asociado está en la base de conocimiento
        public static bool EstaCodigo(String Codigo, int IdCriterioRiesgo)
        {
            bool estaCodigo = false;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<CriteriosRiesgo> Codigos = from CodigosCriterio in agenteBD.CriteriosRiesgoEstablecer
                                                  select CodigosCriterio;
            foreach (CriteriosRiesgo c in Codigos)
            {
                if (c.Equals(Codigo) && c.IdCriterioRiesgo != IdCriterioRiesgo)
                {
                    estaCodigo = true;
                }
            }
            return estaCodigo;
        }

        //Devuelve el número de criterios de riesgo totales en la base de conocimiento
        public static int CriteriosRiesgoTotales()
        {
            int numeroCriterios = 0;
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<CriteriosRiesgo> CritTotal = from Crit in agenteBD.CriteriosRiesgoEstablecer
                                                    select Crit;
            foreach (CriteriosRiesgo Crit in CritTotal)
            {
                numeroCriterios++;
            }
            return numeroCriterios;
        }

        //Devuelve el criterio de riesgo asociado a un nombre
        public static int BuscarIdCriterioRiesgo(String NombreCriterioRiesgo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<int> IdCriterio = from NCriterio in agenteBD.CriteriosRiesgoEstablecer
                                         where NCriterio.CriterioRiesgo == NombreCriterioRiesgo
                                         select NCriterio.IdCriterioRiesgo;
            if (IdCriterio.Count() == 0)
            {
                return -1;
            }
            else
            {
                return IdCriterio.First();
            }
        }

        //Método que recoge los Tipos de Amenazas que están actualmente disponibles en la Base de Conocimiento
        public static List<CriteriosRiesgo> RecogeCriteriosRiesgo()
        {

            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<CriteriosRiesgo> CritRiesgo = from CritRiesg in agenteBD.CriteriosRiesgoEstablecer
                                                     where CritRiesg.Actual == true
                                                     select CritRiesg;
            if (CritRiesgo.Count() == 0)
            {
                //Devolvemos la lista vacía
                return new List<CriteriosRiesgo>();
            }
            return CritRiesgo.ToList();

        }

        //Método que actualiza un criterio de riesgo de la base de conocimiento
        public static void ActualizaCriterioRiesgo(int IdCriterioRiesgo, String Codigo, String CriterioRiesgo, String Descripcion)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            CriteriosRiesgo CR = (from CritRiesg in agenteBD.CriteriosRiesgoEstablecer
                                  where CritRiesg.IdCriterioRiesgo == IdCriterioRiesgo
                                  select CritRiesg).Single();
            CR.Codigo = Codigo;
            CR.CriterioRiesgo = CriterioRiesgo;
            CR.Descripcion = Descripcion;
            agenteBD.SaveChanges();
        }

        //Método que hace un borrado lógico de un Criterio de Riesgo asi como de todos los elementos de las Tablas depedientes de él en la BD
        public static void EliminaCriterioRiesgo(int IdCriterioRiesgo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            CriteriosRiesgo CriterioElim = (from CritRiesg in agenteBD.CriteriosRiesgoEstablecer
                                            where CritRiesg.IdCriterioRiesgo == IdCriterioRiesgo
                                            select CritRiesg).Single();
            CriterioElim.Actual = false;
            agenteBD.SaveChanges();
            //Estructuras para recoger los elementos a eliminar
            //Lista de Relaciones Tipo Activo - Amenaza - Criterio de Riesgo por Criterio de Riesgo
            List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LRelTipActAmenCritPorCritRiesg = new List<Matriz_TipoActivosAmenazasCriteriosRiesgo>();
            //Lista de Instancias Tipo Activo - Amenaza - Criterio de Riesgo por relaciones de ese tipo
            List<InstanciaTiposActivosAmenazasCriteriosRiesgo> LInstTipActCritRiesgoPorRelac = new List<InstanciaTiposActivosAmenazasCriteriosRiesgo>();
            //Recorremos todas las tablas por niveles de dependencia con el Criterio de Riesgo eliminado y actualizamos Actual
            //Nivel 1 de Dependencia: Matriz Tipo Activo - Amenazas - Criterio de Riesgo
            LRelTipActAmenCritPorCritRiesg = Matriz_TipoActivosAmenazasCriteriosRiesgoFactory.EliminaRelacionesPorCriterioRiesgo(IdCriterioRiesgo);
            //Nivel 2 de Dependencia
            if (LRelTipActAmenCritPorCritRiesg.Count != 0)
            {
                //Instancia_TiposActivosAmenazasCriteriosRiesgo
                LInstTipActCritRiesgoPorRelac = InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.EliminaInstanciasPorRelacTipActAmenCrit(LRelTipActAmenCritPorCritRiesg);
            }

        }

        //Método que devuelve el código de un criterio de riesgo 
        public static string CodigoCriterioRiesgo(int IdCriterioRiesgo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> CodigoCriterio = from NCriterio in agenteBD.CriteriosRiesgoEstablecer
                                                where NCriterio.IdCriterioRiesgo == IdCriterioRiesgo
                                                select NCriterio.Codigo;
            if (CodigoCriterio.Count() == 0)
            {
                return "";
            }
            else
            {
                return CodigoCriterio.First();
            }
        }

        //Devuelve la descripción de un criterio de riesgo
        public static string DescripcionCriterioRiesgo(int IdCriterioRiesgo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<String> DescripcionCriterio = from NCriterio in agenteBD.CriteriosRiesgoEstablecer
                                                     where NCriterio.IdCriterioRiesgo == IdCriterioRiesgo
                                                     select NCriterio.Descripcion;
            if (DescripcionCriterio.Count() == 0)
            {
                return "";
            }
            else
            {
                return DescripcionCriterio.First();
            }
        }

        //Método que restaura toda la base de conocimiento de una lista de Criterios de Riesgo
        public static void RestauraCriterioRiesgo(List<int> LCriterioRiesgo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            foreach (int IdCriterioRiesgo in LCriterioRiesgo)
            {
                CriteriosRiesgo CriterioElim = (from CritRiesg in agenteBD.CriteriosRiesgoEstablecer
                                                where CritRiesg.IdCriterioRiesgo == IdCriterioRiesgo
                                                select CritRiesg).Single();
                CriterioElim.Actual = true;
            }
            agenteBD.SaveChanges();
            //Estructuras para recoger los elementos a eliminar
            //Lista de Relaciones Tipo Activo - Amenaza - Criterio de Riesgo por Criterio de Riesgo
            List<Matriz_TipoActivosAmenazasCriteriosRiesgo> LRelTipActAmenCritPorCritRiesg = new List<Matriz_TipoActivosAmenazasCriteriosRiesgo>();
            //Lista de Instancias Tipo Activo - Amenaza - Criterio de Riesgo por relaciones de ese tipo
            List<InstanciaTiposActivosAmenazasCriteriosRiesgo> LInstTipActCritRiesgoPorRelac = new List<InstanciaTiposActivosAmenazasCriteriosRiesgo>();
            //Recorremos todas las tablas por niveles de dependencia con el Criterio de Riesgo eliminado y actualizamos Actual
            //Nivel 1 de Dependencia: Matriz Tipo Activo - Amenazas - Criterio de Riesgo
            LRelTipActAmenCritPorCritRiesg = Matriz_TipoActivosAmenazasCriteriosRiesgoFactory.RestauraRelacionesPorCriterio(LCriterioRiesgo);
            //Nivel 2 de Dependencia
            if (LRelTipActAmenCritPorCritRiesg.Count != 0)
            {
                //Instancia_TiposActivosAmenazasCriteriosRiesgo
                LInstTipActCritRiesgoPorRelac = InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.RestauraInstanciasPorRelacTipActAmenCrit(LRelTipActAmenCritPorCritRiesg);
            }
        }

        //Restaura los criterios de riesgos en la base de conocimiento que haya en la lista 
        internal static void RestauraCriterioPorRelaciones(List<int> LIdsCriterios)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            foreach (int IdCriterioRiesgo in LIdsCriterios)
            {
                //Restauramos los Criterios
                CriteriosRiesgo CritRestaurar = (from Crit in agenteBD.CriteriosRiesgoEstablecer
                                                 where Crit.IdCriterioRiesgo == IdCriterioRiesgo
                                                 select Crit).Single();
                CritRestaurar.Actual = true;
            }
            agenteBD.SaveChanges();
        }

        //Devuelve el número de criterios de riesgo actualmente disponibles en la base de conocimiento
        public static int NumeroCriterios()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NCriterios = (from Crit in agenteBD.CriteriosRiesgoEstablecer
                              where Crit.Actual == true
                              select Crit).Count();
            return NCriterios;
        }

        //Devuelve una lista con los criterios de riesgo eliminados (borrado lógico) de la base de conocimiento
        public static List<CriteriosRiesgo> RecogeCriteriosEliminados()
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<CriteriosRiesgo> LCriterios = new List<CriteriosRiesgo>();
            IQueryable<CriteriosRiesgo> CriteriosQuery = (from cr in agenteBD.CriteriosRiesgoEstablecer
                                                          where cr.Actual == false
                                                          orderby cr.IdCriterioRiesgo
                                                          select cr).Distinct();
            if (CriteriosQuery.Count() != 0)
            {
                LCriterios = CriteriosQuery.ToList();
            }
            return LCriterios;
        }

        //Método que devuelve una lista de criterios en la base de conocimiento cuyos nombres contengan la secuencia de TextoBuscar
        public static List<CriteriosRiesgo> RecogeCriteriosEliminadosPorCriterio(string TextoBuscar)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<CriteriosRiesgo> LCriterios = new List<CriteriosRiesgo>();
            IQueryable<CriteriosRiesgo> CriteriosQuery = (from cr in agenteBD.CriteriosRiesgoEstablecer
                                                          where cr.Actual == false && cr.CriterioRiesgo.Contains(TextoBuscar)
                                                          orderby cr.IdCriterioRiesgo
                                                          select cr).Distinct();
            if (CriteriosQuery.Count() != 0)
            {
                LCriterios = CriteriosQuery.ToList();
            }
            return LCriterios;
        }

        //Método que devuelve una lista de criterios eliminados de la base de conocimiento cuyos nombres contengan la secuencia de TextoBuscar
        public static List<CriteriosRiesgo> RecogeCriteriosEliminadosPorCodigo(string TextoBuscar)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<CriteriosRiesgo> LCriterios = new List<CriteriosRiesgo>();
            IQueryable<CriteriosRiesgo> CriteriosQuery = (from cr in agenteBD.CriteriosRiesgoEstablecer
                                                          where cr.Actual == false && cr.Codigo.Contains(TextoBuscar)
                                                          orderby cr.IdCriterioRiesgo
                                                          select cr).Distinct();
            if (CriteriosQuery.Count() != 0)
            {
                LCriterios = CriteriosQuery.ToList();
            }
            return LCriterios;
        }
    }
}
